package com.guomei.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.guomei.bean.*;
import com.guomei.configs.WechatMpConfig;
import com.guomei.constans.RedisConstants;
import com.guomei.constans.ResultCode;
import com.guomei.constans.RoleCode;

import com.guomei.mapper.UserMapper;
import com.guomei.mapper.UserRoleMapper;
import com.guomei.mapper.curse.CourseDistributerRelMapper;
import com.guomei.mapper.curse.UserDistributorCourseRelMapper;
import com.guomei.bean.curse.domain.CourseDistributerRel;
import com.guomei.bean.curse.domain.UserDistributorCourseRel;
import com.guomei.bean.user.dto.BindDistributorIdDTO;
import com.guomei.service.AliyunOssService;
import com.guomei.service.UserService;
import com.guomei.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;


import java.util.*;
import java.util.stream.Collectors;

import static com.guomei.constans.RedisConstants.*;

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    AliyunOssService aliyunOssService;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private WechatMpConfig wechatMpConfig;
    @Autowired
    private CourseDistributerRelMapper courseDistributerRelMapper;
    @Autowired
    private UserDistributorCourseRelMapper userDistributorCourseRelMapper;



//
//    @Autowired
//    private WechatService wechatService; // 假设已实现微信服务

    @Override
    @Transactional
    public Result<?> register(RegisterDTO registerDTO) {
        // 5. 创建用户
        User user = new User();
//        // 1. 验证验证码
//        String verifyKey = RedisConstants.SMS_CODE_PREFIX + registerDTO.getPhone();
//        String verifyCode = (String)redisUtils.get(verifyKey);
//
//        //解密前端传输的值
        String decryptPassword = AesUtils.decrypt(registerDTO.getPassword());
//        if (verifyCode == null || !verifyCode.equals(registerDTO.getCode())) {
//            return Result.fail("验证码不正确或已过期");
//        }

        // 2. 检查手机号是否已注册
        User existingUser = userMapper.selectByPhone(registerDTO.getPhone());
        if (existingUser != null) {
            return Result.fail("该手机号已注册");
        }

        // 3. 处理邀请码
        Long parentId = null;
        if (StringUtils.hasText(registerDTO.getInvitationCode())) {
            User inviter = userMapper.selectByInvitationCode(registerDTO.getInvitationCode());
            if (inviter == null) {
                Result.fail("邀请码不存在");
            } else {
                parentId = inviter.getId();
            }
        }
        if (registerDTO.isWxAuto() && registerDTO.getTempUserId() != null) {
            // 绑定微信
            // 从Redis中获取临时微信用户信息
            String redisKey = "wechat:temp:user:" + registerDTO.getTempUserId();

            Object tempUserInfoObj = redisUtils.get(redisKey);
            if (!(tempUserInfoObj instanceof Map)) {
                return Result.fail("临时用户信息格式不正确");
            }
            Map<String, Object> tempUserInfo = (Map<String, Object>) tempUserInfoObj;

            if (tempUserInfo == null) {
                return Result.fail("临时用户信息不存在或已过期");
            }

            // 将Map转换为WechatUserInfo对象
            WechatUserInfo wechatUserInfo = new WechatUserInfo();
            wechatUserInfo.setOpenid((String) tempUserInfo.get("openid"));
            wechatUserInfo.setUnionid((String) tempUserInfo.get("unionid"));
            wechatUserInfo.setNickname((String) tempUserInfo.get("nickname"));
            wechatUserInfo.setHeadimgurl((String) tempUserInfo.get("headimgurl"));
            if (wechatUserInfo == null) {
                return Result.fail("微信授权失败");
            }
            user.setWechatOpenid(wechatUserInfo.getOpenid());
            user.setWechatUnionid(wechatUserInfo.getUnionid());
            user.setParentId(parentId);
            user.setNickname(wechatUserInfo.getNickname());
            if(wechatUserInfo.getHeadimgurl() != null){
                user.setAvatar(wechatUserInfo.getHeadimgurl());
            } else {
                if (registerDTO.getAvatar() != null){
                    user.setAvatar(registerDTO.getAvatar());
                }
            }
            user.setStatus(1);
            user.setInvitationCode(InvitationCodeUtils.generateInvitationCode());
            user.setCreatedTime(new Date());
            user.setUpdatedTime(new Date());
            userMapper.insert(user);
        } else {
            // 5. 创建用户
            user.setPhone(registerDTO.getPhone());
            //加密传输数据库
            user.setPassword(PasswordUtils.encryptPassword(decryptPassword));
            if (registerDTO.getNickname() == null || registerDTO.getNickname().isEmpty()){
                user.setNickname("用户" + registerDTO.getPhone().substring(7)); // 默认昵称
            } else{
                user.setNickname(registerDTO.getNickname());
            }
            user.setStatus(1); // 正常状态
            user.setInvitationCode(InvitationCodeUtils.generateInvitationCode());
            user.setParentId(parentId);
            user.setCreatedTime(new Date());
            user.setUpdatedTime(new Date());
            if (registerDTO.getAvatar() != null) {
                user.setAvatar(registerDTO.getAvatar());
            }

            userMapper.insert(user);
        }

        // 6. 默认不分配角色，没有分配角色，默认为学生，其余角色需要后台管理系统分配角色
        UserRole userRole = new UserRole();
        userRole.setUserId(user.getId());
        userRole.setRoleCode(String.valueOf(RoleCode.STUDENT.getCode()));
        userRole.setCreatedTime(new Date());
        // userRole.setUpdatedTime(new Date());

        userRoleMapper.insert(userRole);
        //删除验证码
//        redisUtils.delete(verifyKey);
        return Result.success(user);
    }

    @Override
    public Result<?> loginByPassword(LoginDTO loginDTO) {
        String decryptPassword = AesUtils.decrypt(loginDTO.getPassword());
        // 1. 查询用户
        User user = userMapper.selectByPhone(loginDTO.getPhone());
        if (user == null) {
            return Result.fail("用户不存在");
        }

        // 2. 检查状态
        if (user.getStatus() == 0) {
            return Result.fail("账号已被禁用");
        }
//        String encryptPassword = PasswordUtils.encryptPassword(encryptPassword);
        // 3. TODO: 验证密码
        // if (!PasswordUtils.matchesPassword(decryptPassword, user.getPassword())) {
        //     return Result.fail("密码不正确");
        // }

        // 5. 生成token并返回结果
        return generateLoginResult(user);
    }

    @Override
    public Result<?> loginByCode(LoginDTO loginDTO) {
        // 1. 验证验证码
        String verifyKey = RedisConstants.SMS_CODE_PREFIX + loginDTO.getPhone();
        String verifyCode = (String)redisUtils.get(verifyKey);
        if (verifyCode == null || !verifyCode.equals(loginDTO.getCode())) {
            return Result.error("验证码不正确或已过期");
        }

        // 2. 查询用户，不存在则自动注册
        User checkUser = userMapper.selectByPhone(loginDTO.getPhone());
        // 5. 创建用户
        User user = new User();
        if (checkUser == null) {
            user.setPhone(loginDTO.getPhone());
//        user.setPassword(PasswordUtils.encryptPassword(registerDTO.getPassword()));
            user.setNickname("用户" + loginDTO.getPhone().substring(7)); // 默认昵称
            user.setStatus(1); // 正常状态
            user.setInvitationCode(InvitationCodeUtils.generateInvitationCode());
            user.setCreatedTime(new Date());
            user.setUpdatedTime(new Date());

            userMapper.insert(user);

            // 6. 默认不分配角色，没有分配角色，默认为学生，其余角色需要后台管理系统分配角色
            UserRole userRole = new UserRole();
            userRole.setUserId(user.getId());
            userRole.setRoleCode(String.valueOf(RoleCode.STUDENT.getCode()));
            userRole.setCreatedTime(new Date());
            // userRole.setUpdatedTime(new Date());

            userRoleMapper.insert(userRole);
            Result<?> result = generateLoginResult(user);
            //删除验证码
            redisUtils.delete(verifyKey);
            // 5. 生成token并返回结果
            return result;
        }

        // 3. 检查状态
        if (checkUser.getStatus() == 0) {
            return Result.fail("账号已被禁用");
        }
        Result<?> result = generateLoginResult(checkUser);
        //删除验证码
        redisUtils.delete(verifyKey);
        // 5. 生成token并返回结果
        return result;
    }
    @Override
    public Result<?> generateTempQrCode(Integer sceneId, Integer userId) {
        try {
            String accessToken = getAccessToken();
            if (accessToken == null) {
                return Result.error("获取微信access_token失败");
            }

            // 构造请求参数
            Map<String, Object> params = new HashMap<>();
            params.put("expire_seconds", 600); // 10分钟有效
            params.put("action_name", "QR_SCENE");
            Map<String, Object> actionInfo = new HashMap<>();
            Map<String, Object> scene = new HashMap<>();
            scene.put("scene_id", sceneId);
            actionInfo.put("scene", scene);
            params.put("action_info", actionInfo);

            String url = wechatMpConfig.getQrcodeCreateUrl() + "?access_token=" + accessToken;
            String response = HttpUtils.postJson(url, JSON.toJSONString(params));

            JSONObject jsonObject = JSON.parseObject(response);
            if (jsonObject.containsKey("errcode") && jsonObject.getIntValue("errcode") != 0) {
                return Result.error("生成二维码失败: " + jsonObject.getString("errmsg"));
            }

            WechatQrCode qrCode = new WechatQrCode();
            qrCode.setTicket(jsonObject.getString("ticket"));
            qrCode.setExpireSeconds(jsonObject.getIntValue("expire_seconds"));
            qrCode.setQrCodeUrl(wechatMpConfig.getQrcodeShowUrl() + "?ticket=" + qrCode.getTicket());
            qrCode.setQrCodeId("QR_" + sceneId);

            // 存储到Redis
            String redisKey = WECHAT_QR_CODE_PREFIX + qrCode.getQrCodeId();
            
            // 如果 userId 不为空，表示需要绑定微信到现有用户
            if (userId != null) {
                Map<String, Object> qrCodeInfo = new HashMap<>();
                qrCodeInfo.put("qrCodeId", qrCode.getQrCodeId());
                qrCodeInfo.put("userId", userId);
                qrCodeInfo.put("bindMode", true);
                qrCodeInfo.put("createTime", System.currentTimeMillis());
                redisUtils.set(redisKey, qrCodeInfo, 600L);
                log.info("生成绑定二维码: sceneId={}, userId={}, qrCodeId={}", sceneId, userId, qrCode.getQrCodeId());
            } else {
                // 普通登录二维码，只存储 qrCodeId
                redisUtils.set(redisKey, qrCode.getQrCodeId(), 600L);
                log.info("生成登录二维码: sceneId={}, qrCodeId={}", sceneId, qrCode.getQrCodeId());
            }

            return Result.success(qrCode);
        } catch (Exception e) {
            log.error("生成微信临时二维码失败", e);
            return Result.error("生成二维码失败: " + e.getMessage());
        }
    }

    @Override
    public WechatQrCode generatePermanentQrCode(String sceneStr) {
        try {
            String accessToken = getAccessToken();
            if (accessToken == null) {
                throw new RuntimeException("获取微信access_token失败");
            }

            // 构造请求参数
            Map<String, Object> params = new HashMap<>();
            params.put("action_name", "QR_STR_SCENE");
            Map<String, Object> actionInfo = new HashMap<>();
            Map<String, Object> scene = new HashMap<>();
            scene.put("scene_str", sceneStr);
            actionInfo.put("scene", scene);
            params.put("action_info", actionInfo);

            String url = wechatMpConfig.getQrcodeCreateUrl() + "?access_token=" + accessToken;
            String response = HttpUtils.postJson(url, JSON.toJSONString(params));

            JSONObject jsonObject = JSON.parseObject(response);
            if (jsonObject.containsKey("errcode") && jsonObject.getIntValue("errcode") != 0) {
                throw new RuntimeException("生成二维码失败: " + jsonObject.getString("errmsg"));
            }

            WechatQrCode qrCode = new WechatQrCode();
            qrCode.setTicket(jsonObject.getString("ticket"));
            qrCode.setExpireSeconds(-1); // 永久二维码
            qrCode.setQrCodeUrl(wechatMpConfig.getQrcodeShowUrl() + "?ticket=" + qrCode.getTicket());
            qrCode.setQrCodeId(sceneStr);

            return qrCode;
        } catch (Exception e) {
            log.error("生成微信永久二维码失败", e);
            throw new RuntimeException("生成二维码失败: " + e.getMessage());
        }
    }
    @Override
    public WechatUserInfo getUserInfoByCode(String code) {
        try {
            // 通过code获取access_token和openid
            String tokenUrl = wechatMpConfig.getOauth2AccessTokenUrl() +
                    "?appid=" + wechatMpConfig.getAppid() +
                    "&secret=" + wechatMpConfig.getSecret() +
                    "&code=" + code +
                    "&grant_type=authorization_code";

            String tokenResponse = HttpUtils.get(tokenUrl, null);
            JSONObject tokenJson = JSON.parseObject(tokenResponse);

            if (tokenJson.containsKey("errcode")) {
                throw new RuntimeException("获取access_token失败: " + tokenJson.getString("errmsg"));
            }

            String accessToken = tokenJson.getString("access_token");
            String openid = tokenJson.getString("openid");

            // 获取用户信息
            return getUserInfoByOpenid(openid);
        } catch (Exception e) {
            log.error("通过code获取微信用户信息失败", e);
            throw new RuntimeException("获取用户信息失败: " + e.getMessage());
        }
    }

    @Override
    public WechatUserInfo getUserInfoByOpenid(String openid) {
        try {
            String accessToken = getAccessToken();
            if (accessToken == null) {
                throw new RuntimeException("获取微信access_token失败");
            }

            String url = wechatMpConfig.getUserInfoUrl() +
                    "?access_token=" + accessToken +
                    "&openid=" + openid +
                    "&lang=zh_CN";

            String response = HttpUtils.get(url,null);
            JSONObject jsonObject = JSON.parseObject(response);

            if (jsonObject.containsKey("errcode") && jsonObject.getIntValue("errcode") != 0) {
                throw new RuntimeException("获取用户信息失败: " + jsonObject.getString("errmsg"));
            }

            WechatUserInfo userInfo = new WechatUserInfo();
            userInfo.setOpenid(jsonObject.getString("openid"));
            userInfo.setUnionid(jsonObject.getString("unionid"));
            userInfo.setNickname(jsonObject.getString("nickname"));
            userInfo.setHeadimgurl(jsonObject.getString("headimgurl"));
            userInfo.setSex(jsonObject.getInteger("sex"));
            userInfo.setProvince(jsonObject.getString("province"));
            userInfo.setCity(jsonObject.getString("city"));
            userInfo.setCountry(jsonObject.getString("country"));
            userInfo.setLanguage(jsonObject.getString("language"));
            userInfo.setSubscribe(jsonObject.getInteger("subscribe"));
            userInfo.setSubscribeTime(jsonObject.getLong("subscribe_time"));

            return userInfo;
        } catch (Exception e) {
            log.error("获取微信用户信息失败", e);
            throw new RuntimeException("获取用户信息失败: " + e.getMessage());
        }
    }

    @Override
    public String getAccessToken() {
        try {
            // 先从Redis中获取缓存的access_token
            String cachedToken = (String) redisUtils.get(WECHAT_ACCESS_TOKEN_KEY);
            if (cachedToken != null) {
                return cachedToken;
            }

            String url = wechatMpConfig.getAccessTokenUrl() +
                    "?grant_type=client_credential" +
                    "&appid=" + wechatMpConfig.getAppid() +
                    "&secret=" + wechatMpConfig.getSecret();

            String response = HttpUtils.get(url,null);
            JSONObject jsonObject = JSON.parseObject(response);

            if (jsonObject.containsKey("errcode")) {
                throw new RuntimeException("获取access_token失败: " + jsonObject.getString("errmsg"));
            }

            String accessToken = jsonObject.getString("access_token");
            int expiresIn = jsonObject.getIntValue("expires_in");

            // 缓存到Redis中，提前5分钟过期
            redisUtils.set(WECHAT_ACCESS_TOKEN_KEY, accessToken, expiresIn - 300L);

            return accessToken;
        } catch (Exception e) {
            log.error("获取微信access_token失败", e);
            return null;
        }
    }

    @Override
    public boolean processCallback(String code, String state) {
        try {
            // 将授权码存储到Redis中
            String redisKey = WECHAT_QR_CODE_SCANNED_PREFIX + state;
            redisUtils.set(redisKey, code, 300L); // 5分钟过期

            // 标记二维码已被扫描
            String qrCodeKey = WECHAT_QR_CODE_PREFIX + state;
            redisUtils.set(qrCodeKey + ":status", "scanned", 300L);

            return true;
        } catch (Exception e) {
            log.error("处理微信回调失败", e);
            return false;
        }
    }

    @Override
    public Result<?> checkQrCodeScanStatus(String qrCodeId) {
        try {
            // 直接查询二维码ID对应的Redis key
            // 前端传入qrCodeId (如: "QR_123456")，我们直接用这个作为key查询
            String qrCodeKey = WECHAT_QR_CODE_PREFIX + qrCodeId;
            Object scanData = redisUtils.get(qrCodeKey);
            
            if (scanData == null) {
                // 二维码未被扫描或已过期
                Map<String, Object> data = new HashMap<>();
                data.put("status", "waiting");
                data.put("message", "等待扫码");
                data.put("qrCodeId", qrCodeId);
                return Result.success(data);
            }
            
            // 检查是否是扫码结果数据
            if (scanData instanceof Map) {
                Map<String, Object> scanResult = (Map<String, Object>) scanData;
                
                // 如果包含登录结果，说明已经扫码
                if (scanResult.containsKey("loginResult") || scanResult.containsKey("openid")) {
                    Map<String, Object> responseData = new HashMap<>();
                    responseData.put("status", "scanned");
                    responseData.put("qrCodeId", qrCodeId);
                    responseData.put("openid", scanResult.get("openid"));
                    responseData.put("timestamp", scanResult.get("timestamp"));
                    responseData.put("sceneId", scanResult.get("sceneId"));
                    responseData.put("eventKey", scanResult.get("eventKey"));
                    
                    // 检查是否有登录结果
                    if (scanResult.containsKey("loginResult")) {
                        Result<?> loginResult = (Result<?>) scanResult.get("loginResult");
                        responseData.put("loginResult", loginResult);
                        
                        if (loginResult.getCode() == 200) {
                            responseData.put("message", "扫码登录成功");
                            responseData.put("success", true);
                        } else {
                            responseData.put("message", "扫码失败");
                            responseData.put("success", false);
                        }
                    } else if (scanResult.containsKey("error")) {
                        responseData.put("message", (String) scanResult.get("error"));
                        responseData.put("success", false);
                    } else {
                        responseData.put("message", "扫码成功，处理中...");
                        responseData.put("success", true);
                    }
                    
                    return Result.success(responseData);
                } else {
                    // 可能是原始的二维码信息（还未扫码）
                    Map<String, Object> data = new HashMap<>();
                    data.put("status", "waiting");
                    data.put("message", "等待扫码");
                    data.put("qrCodeId", qrCodeId);
                    return Result.success(data);
                }
            }
            
            // 兼容其他格式
            Map<String, Object> data = new HashMap<>();
            data.put("status", "waiting");
            data.put("message", "等待扫码");
            data.put("qrCodeId", qrCodeId);
            return Result.success(data);
            
        } catch (Exception e) {
            log.error("检查二维码状态失败: qrCodeId={}", qrCodeId, e);
            return Result.error("检查状态失败: " + e.getMessage());
        }
    }

    @Override
    public Result<?> getUserById(Long id) {
        User user = userMapper.selectById(id);
        if (user == null){
            return Result.fail("用户不存在");
        }
        return Result.success(user);
    }
    
    @Override
    public Result<com.guomei.bean.user.vo.UserInfo> getUserInfoWithRoles(Long id) {
        try {
            if (id == null) {
                return Result.fail("用户ID不能为空");
            }
            
            com.guomei.bean.user.vo.UserInfo userInfo = userMapper.selectUserInfoWithRoleById(id);
            if (userInfo == null) {
                return Result.fail("用户不存在");
            }
            
            log.debug("查询到用户信息: userId={}, 昵称={}, 角色数量={}", 
                    id, userInfo.getNickname(), 
                    userInfo.getUserRoles() != null ? userInfo.getUserRoles().size() : 0);
            
            return Result.success(userInfo);
            
        } catch (Exception e) {
            log.error("查询用户信息失败: userId={}", id, e);
            return Result.fail("查询用户信息失败: " + e.getMessage());
        }
    }

    @Override
    public User getUserByPhone(String phone) {
        return userMapper.selectByPhone(phone);
    }


    /**
     * 生成登录结果
     */
    private Result<?> generateLoginResult(User user) {
        Role role =null;
        // 构建返回结果
        LoginResultDTO userInfoDTO = new LoginResultDTO();
        // 获取用户角色
        List<UserRole> userRoles = userRoleMapper.selectByUserId(user.getId());
        ArrayList<String> roleCodeList = new ArrayList<>();


//        if (userRoles != null && !userRoles.isEmpty()){
//            Optional<UserRole> maxRole = userRoles.stream()
//                    .filter(userRole -> userRole.getRoleCode() != null)
//                    .max(Comparator.comparingInt(userRole -> Integer.parseInt(userRole.getRoleCode())));
//            if (maxRole.isPresent()) {
//                String maxCode = maxRole.get().getRoleCode(); // 正确获取 roleCode 字符串
//                // 如果需要设置角色信息，应该查询 Role 表或根据 roleCode 构造 Role 对象
//                // 示例：Role role = roleMapper.selectByRoleCode(maxCode);
//                userInfoDTO.setRoleCode(maxCode);
//            }
//        }
        if (userRoles != null && !userRoles.isEmpty()){
            for (UserRole userRole : userRoles) {
                roleCodeList.add(userRole.getRoleCode());
            }
        }

        // 生成accessToken和refreshToken
        String accessToken = JwtUtil.generateAccessToken(user.getId(), user.getPhone());
        String refreshToken = JwtUtil.generateRefreshToken(user.getId(), user.getPhone());

        if (user.getPassword() == null) {
            userInfoDTO.setInPassword(false);
        } else {
            userInfoDTO.setInPassword(true);
        }
        userInfoDTO.setId(user.getId());
        userInfoDTO.setRoleCode(roleCodeList);
        userInfoDTO.setPhone(user.getPhone());
        userInfoDTO.setNickname(user.getNickname());
        userInfoDTO.setRealName(user.getRealName());
        userInfoDTO.setAvatar(user.getAvatar());
        userInfoDTO.setAccessToken(accessToken); // 添加accessToken字段
        userInfoDTO.setRefreshToken(refreshToken); // 添加refreshToken字段
        userInfoDTO.setNeedBindPhone(false); // 根据业务需求设置
        userInfoDTO.setTempToken(null); // 根据业务需求设置
        return Result.success(userInfoDTO);
    }

    @Override
    public Result<?> autoRegister(WechatUserInfo wechatUserInfo){
        try {
            // 1. 查询用户，不存在则准备注册
            User checkUser = userMapper.selectByWechatOpenid(wechatUserInfo.getOpenid());

            if (checkUser == null) {
                // 新用户，需要绑定手机号
                // 生成临时用户标识，让用户去绑定手机号
                String tempUserId = "TEMP_" + System.currentTimeMillis() + "_" + wechatUserInfo.getOpenid().substring(0, 8);

                // 将微信用户信息临时存储到Redis中，等待用户绑定手机号
                String redisKey = "wechat:temp:user:" + tempUserId;
                Map<String, Object> tempUserInfo = new HashMap<>();
                tempUserInfo.put("openid", wechatUserInfo.getOpenid());
                tempUserInfo.put("unionid", wechatUserInfo.getUnionid());
                tempUserInfo.put("nickname", wechatUserInfo.getNickname());
                tempUserInfo.put("headimgurl", wechatUserInfo.getHeadimgurl());
                tempUserInfo.put("createTime", System.currentTimeMillis());

                // 存储10分钟
                redisUtils.set(redisKey, tempUserInfo, 600L);

                // 返回临时标识，让前端引导用户绑定手机号
                Map<String, Object> resultData = new HashMap<>();
                resultData.put("tempUserId", tempUserId);
                resultData.put("needBindPhone", true);
                resultData.put("message", "请绑定手机号完成注册");

                return Result.fail(ResultCode.FAIL.getCode(),"需要绑定手机号", resultData);
            }
            if (checkUser.getWechatOpenid() == null) {
                userMapper.bindWechat(checkUser.getId(), wechatUserInfo.getOpenid(), wechatUserInfo.getUnionid());
            }

            // 2. 老用户，检查状态
            if (checkUser.getStatus() == 0) {
                return Result.fail("账号已被禁用");
            }

            // 3. 生成登录结果
            return generateLoginResult(checkUser);
        } catch (Exception e) {
            log.error("微信自动注册处理失败", e);
            return Result.error("处理失败: " + e.getMessage());
        }
   }

    @Override
    @Transactional
    public Result<?> autoCreateUserByQrScan(String openid){
        try {
            // 1. 查询用户是否已存在
            User checkUser = userMapper.selectByWechatOpenid(openid);
            
            if (checkUser != null) {
                // 用户已存在，检查状态
                if (checkUser.getStatus() == 0) {
                    return Result.fail("账号已被禁用");
                }
                
                // 更新最后登录时间
                checkUser.setLastLoginTime(new Date());
                userMapper.update(checkUser);
                
                // 直接返回登录结果
                return generateLoginResult(checkUser);
            }

            // 2. 获取微信用户信息
            WechatUserInfo wechatUserInfo;
            try {
                wechatUserInfo = getUserInfoByOpenid(openid);
                if (wechatUserInfo == null) {
                    return Result.error("获取微信用户信息失败");
                }
            } catch (Exception e) {
                log.error("获取微信用户信息失败: {}", e.getMessage(), e);
                return Result.error("获取用户信息失败，无法创建用户");
            }

            // 3. 创建新用户
            User newUser = new User();
            newUser.setWechatOpenid(wechatUserInfo.getOpenid());
            newUser.setWechatUnionid(wechatUserInfo.getUnionid());
            
            // 设置昵称，如果微信昵称为空则使用默认昵称
            if (StringUtils.hasText(wechatUserInfo.getNickname())) {
                newUser.setNickname(wechatUserInfo.getNickname());
            } else {
                newUser.setNickname("微信用户" + openid.substring(openid.length() - 6));
            }
            
            // 设置头像
            if (StringUtils.hasText(wechatUserInfo.getHeadimgurl())) {
                newUser.setAvatar(wechatUserInfo.getHeadimgurl());
            }
            
            newUser.setStatus(1); // 正常状态
            newUser.setInvitationCode(InvitationCodeUtils.generateInvitationCode());
            newUser.setLastLoginTime(new Date());
            newUser.setCreatedTime(new Date());
            newUser.setUpdatedTime(new Date());
            
            // 插入用户
            userMapper.insert(newUser);
            
            // 4. 分配默认学生角色
            UserRole userRole = new UserRole();
            userRole.setUserId(newUser.getId());
            userRole.setRoleCode(String.valueOf(RoleCode.STUDENT.getCode()));
            userRole.setCreatedTime(new Date());
            // userRole.setUpdatedTime(new Date());
            userRoleMapper.insert(userRole);
            
            log.info("微信扫码自动创建用户成功: openid={}, userId={}", openid, newUser.getId());
            
            // 5. 返回登录结果
            return generateLoginResult(newUser);
            
        } catch (Exception e) {
            log.error("微信扫码自动创建用户失败: openid={}", openid, e);
            return Result.error("创建用户失败: " + e.getMessage());
        }
    }

    /**
     * 绑定微信到现有用户
     */
    @Transactional(rollbackFor = Exception.class)
    private Result<?> bindWechatToUser(Long userId, String openid) {
        try {
            log.info("开始绑定微信到用户: userId={}, openid={}", userId, openid);
            
            // 1. 查询目标用户是否存在
            User targetUser = userMapper.selectById(userId);
            if (targetUser == null) {
                return Result.error("用户不存在");
            }
            
            // 2. 检查用户状态
            if (targetUser.getStatus() == 0) {
                return Result.fail("账号已被禁用");
            }
            
            // 3. 检查该微信是否已绑定其他用户
            User existingWechatUser = userMapper.selectByWechatOpenid(openid);
            if (existingWechatUser != null) {
                if (existingWechatUser.getId().equals(userId)) {
                    // 已绑定到当前用户，直接返回登录结果
                    log.info("微信已绑定到当前用户: userId={}, openid={}", userId, openid);
                    targetUser.setLastLoginTime(new Date());
                    userMapper.update(targetUser);
                    return generateLoginResult(targetUser);
                } else {
                    // 已绑定到其他用户
                    return Result.error("该微信已绑定到其他账号");
                }
            }
            
            // 4. 检查该用户是否已绑定其他微信
            if (StringUtils.hasText(targetUser.getWechatOpenid())) {
                return Result.error("该账号已绑定其他微信，请先解绑");
            }
            
            // 5. 获取微信用户信息
            WechatUserInfo wechatUserInfo;
            try {
                wechatUserInfo = getUserInfoByOpenid(openid);
                if (wechatUserInfo == null) {
                    log.warn("获取微信用户信息失败，继续绑定操作: openid={}", openid);
                    // 即使获取用户信息失败，也继续绑定
                }
            } catch (Exception e) {
                log.error("获取微信用户信息失败: {}", e.getMessage(), e);
                wechatUserInfo = null;
            }
            
            // 6. 更新用户微信信息
            targetUser.setWechatOpenid(openid);
            if (wechatUserInfo != null) {
                targetUser.setWechatUnionid(wechatUserInfo.getUnionid());
                // 如果用户没有头像，使用微信头像
                if (!StringUtils.hasText(targetUser.getAvatar()) && StringUtils.hasText(wechatUserInfo.getHeadimgurl())) {
                    targetUser.setAvatar(wechatUserInfo.getHeadimgurl());
                }
            }
            targetUser.setLastLoginTime(new Date());
            targetUser.setUpdatedTime(new Date());
            
            // 7. 保存到数据库
            int updated = userMapper.update(targetUser);
            if (updated > 0) {
                log.info("微信绑定成功: userId={}, openid={}", userId, openid);
                
                // 8. 返回登录结果
                return generateLoginResult(targetUser);
            } else {
                return Result.error("绑定失败，请稍后重试");
            }
            
        } catch (Exception e) {
            log.error("绑定微信到用户失败: userId={}, openid={}", userId, openid, e);
            return Result.error("绑定失败: " + e.getMessage());
        }
    }

    @Override
    public Result<?> changePassword(ChangePassword changePassword) {
        try {
            User user = userMapper.selectById(changePassword.getUserId());
            if (user == null) {
                return Result.fail("用户不存在");
            }
            //解密前端传输的值
            String decryptPassword = AesUtils.decrypt(changePassword.getNewPassword());
            String s = PasswordUtils.encryptPassword(decryptPassword);
            user.setPassword(s);
            userMapper.update(user);
            return Result.success("修改成功");
        } catch (Exception e) {
            log.error("修改密码处理失败", e);
            return Result.error("处理失败: " + e.getMessage());
        }
    }

    @Override
    public Result<?> getALLUser(GetAllUserDTO getAllUserDTO) {

        // 验证分页参数是否有效
        if (getAllUserDTO.getPageNum() <= 0 || getAllUserDTO.getPageSize() <= 0) {
            return Result.fail("分页参数无效");
        }


        List<Long> ids = userRoleMapper.selectUserIdByRoleCode(null);
        // 使用 Stream API 去重
        List<Long> distinctList = ids.stream()
                .distinct()
                .collect(Collectors.toList());
        if (ids == null ||ids.isEmpty()){
            return Result.fail("无法查询到用户列表信息");
        }

        // 如果指定了特定用户ID，则只保留该用户ID
        if (getAllUserDTO.getUserId() != null) {
            // 检查指定的用户ID是否在结果集中
            if (distinctList.contains(getAllUserDTO.getUserId())) {
                // 清空列表，只保留指定的用户ID
                distinctList.clear();
                distinctList.add(getAllUserDTO.getUserId());
            } else {
                // 用户ID不存在于结果集中，返回错误
                return Result.fail("用户ID不存在");
            }
        }
//// 使用迭代器安全地遍历和删除元素
//        Iterator<Long> iterator = ids.iterator();
//        while (iterator.hasNext()) {
//            Long zid = iterator.next();
//            // 如果大于1，说明有其他角色，进行删除
//            List<UserRole> userRoles = userRoleMapper.selectByUserId(zid);
//            if (userRoles != null && userRoles.size() > 1) {
//                // 使用迭代器删除当前元素
//                iterator.remove();
//            }
//        }
        // 使用PageHelper进行分页查询
        PageHelper.startPage(getAllUserDTO.getPageNum(), getAllUserDTO.getPageSize());
        // 使用新的查询方法，支持关键词搜索并预加载角色信息，返回UserInfo对象
        List<User> users = userMapper.selectUserInfoWithRoleByIds1(distinctList, getAllUserDTO.getKeyword());
        for (User user : users) {
            List<UserRole> userRoles = userRoleMapper.selectByUserId(user.getId());
            user.setUserRoles(userRoles);
        }
        // 封装分页结果到PageData
        PageData<User> pageData = new PageData<>();
        PageInfo<User> pageInfo = new PageInfo<>(users);
        pageData.setTotal(pageInfo.getTotal());
        pageData.setData(pageInfo.getList());
        pageData.setPageNum(getAllUserDTO.getPageNum());
        pageData.setPageSize(getAllUserDTO.getPageSize());
        return Result.success(pageData);
    }

    @Override
    public Result<?> getALLTeacher(GetAllUserDTO getAllUserDTO) {
        
        // 验证分页参数是否有效
        if (getAllUserDTO.getPageNum() <= 0 || getAllUserDTO.getPageSize() <= 0) {
            return Result.fail("分页参数无效");
        }
        
        ArrayList<String> roleCode = new ArrayList<>();
        //值是固定的
        roleCode.add(String.valueOf(RoleCode.INSTRUCTOR.getCode()));
        roleCode.add(String.valueOf(RoleCode.ADMISSIONS_TEACHER.getCode()));
//        roleCode.add(String.valueOf(RoleCode.EXAM_GRADING.getCode()));
        List<Long> ids = userRoleMapper.selectUserIdByRoleCode(roleCode);
        if (ids.isEmpty()){
            return Result.fail("无法查询到教师人员");
        }

        // 使用 Stream API 去重
        List<Long> distinctList = ids.stream()
                .distinct()
                .collect(Collectors.toList());

        // 如果指定了特定用户ID，则只保留该用户ID
        if (getAllUserDTO.getUserId() != null) {
            // 检查指定的用户ID是否在结果集中
            if (distinctList.contains(getAllUserDTO.getUserId())) {
                // 清空列表，只保留指定的用户ID
                distinctList.clear();
                distinctList.add(getAllUserDTO.getUserId());
            } else {
                // 用户ID不存在于结果集中，返回错误
                return Result.fail("教师ID不存在");
            }
        }

        // 使用PageHelper进行分页查询
        PageHelper.startPage(getAllUserDTO.getPageNum(), getAllUserDTO.getPageSize());
        // 使用新的查询方法，支持关键词搜索并预加载角色信息，返回UserInfo对象
        List<User> users = userMapper.selectUserInfoWithRoleByIds1(distinctList, getAllUserDTO.getKeyword());
        for (User user : users) {
            List<UserRole> userRoles = userRoleMapper.selectByUserId(user.getId());
            user.setUserRoles(userRoles);
        }
        // 封装分页结果到PageData
        PageData<User> pageData = new PageData<>();
        PageInfo<User> pageInfo = new PageInfo<>(users);
        pageData.setTotal(pageInfo.getTotal());
        pageData.setData(pageInfo.getList());
        pageData.setPageNum(getAllUserDTO.getPageNum());
        pageData.setPageSize(getAllUserDTO.getPageSize());
        return Result.success(pageData);
    }

    @Override
    public Result<?> deleteRole(DeleteRoleDTO deleteRoleDTO) {
        try {
            boolean isIn = userRoleMapper.checkUserHasRole(deleteRoleDTO.getOperatorId(),String.valueOf(RoleCode.BACKEND_ADMINISTRATOR.getCode()));
            if (!isIn){
                return Result.fail("操作角色没有权限删除用户角色");
            }
            int i = userRoleMapper.deleteByUserIdIdAndRoleId(deleteRoleDTO.getUserId(), deleteRoleDTO.getRoleCode());
            if (i <= 0){
                return Result.fail("删除失败");
            }
            return Result.success("删除成功");
        } catch (Exception e) {
            log.error("删除角色处理失败", e);
            return Result.error("处理失败: " + e.getMessage());
        }
    }

    @Override
    public boolean verifyWechatSignature(String signature, String timestamp, String nonce) {
        try {
            return WechatCryptoUtil.verifySignature(wechatMpConfig.getToken(), timestamp, nonce, signature);
        } catch (Exception e) {
            log.error("验证微信签名失败", e);
            return false;
        }
    }

    @Override
    public Object handleWechatMessage(String signature, String timestamp, String nonce, String msgSignature, String encryptType, String requestBody) {
        try {
            // 1. 验证基础签名
            if (!verifyWechatSignature(signature, timestamp, nonce)) {
                log.warn("微信签名验证失败");
                return "fail";
            }

            // 2. 解析请求体
            WechatMessage message = null;

            if ("aes".equals(encryptType)) {
                // 安全模式 - 需要解密
                message = handleEncryptedMessage(requestBody, msgSignature, timestamp, nonce);
            } else {
                // 明文模式
                message = handlePlainMessage(requestBody);
            }

            if (message == null) {
                log.error("消息解析失败");
                return "fail";
            }

            // 3. 处理消息
            String replyContent = processMessage(message);

            // 4. 返回响应
            if ("aes".equals(encryptType) && replyContent != null && !replyContent.isEmpty()) {
                // 加密模式返回
                return createEncryptedResponse(replyContent, timestamp, nonce);
            } else {
                // 明文模式返回
                return StringUtils.hasText(replyContent) ? replyContent : "success";
            }

        } catch (Exception e) {
            log.error("处理微信消息失败", e);
            return "fail";
        }
    }

    @Override
    public Result<?> updateUser(UpdateUser updateUser) {
        User updateUserData = new User();
        //查询是否存在这个用户
        User user = userMapper.selectById(updateUser.getId());
        if (user == null) {
            return Result.fail("用户不存在");
        }
        updateUserData.setId(updateUser.getId());
        updateUserData.setNickname(updateUser.getNickname());
        updateUserData.setRealName(updateUser.getRealName());
        updateUserData.setIdCard(updateUser.getIdCard());
        updateUserData.setAddress(updateUser.getAddress());
        updateUserData.setAvatar(updateUser.getAvatar());
        updateUserData.setDescription(updateUser.getDescription());
        updateUserData.setStatus(1);
        updateUserData.setPhone(updateUser.getPhone());

        if (updateUser.getNewPassword() != null){
            String decryptPassword = AesUtils.decrypt(updateUser.getNewPassword());
            String s = PasswordUtils.encryptPassword(decryptPassword);
            updateUserData.setPassword(s);
        }


        userMapper.update(updateUserData);
        if (user.getAvatar() != null && updateUser.getAvatar() != null){
            boolean b = aliyunOssService.deleteFile(user.getAvatar());
        }
        log.info("删除用户头像成功：{}", user.getAvatar());
        return Result.success("个人信息更新成功");

    }

    @Override
    public Result<?> assignRoleToUser(List<UserRole> userRoles, Long userId) {
        try {
            if (userId == null) {
                return Result.fail("用户ID不能为空");
            }
            if (userRoles == null) {
                return Result.fail("用户角色列表不能为空");
            }
            
            // 获取前端传入的角色编码列表
            List<String> newRoleCodes = userRoles.stream()
                    .filter(role -> role.getRoleCode() != null && !role.getRoleCode().trim().isEmpty())
                    .map(role -> role.getRoleCode().trim())
                    .distinct()
                    .collect(java.util.stream.Collectors.toList());
            
            // 获取用户当前的角色列表
            List<UserRole> currentUserRoles = userRoleMapper.selectByUserId(userId);
            List<String> currentRoleCodes = currentUserRoles.stream()
                    .map(UserRole::getRoleCode)
                    .collect(java.util.stream.Collectors.toList());
            
            int addCount = 0;
            int removeCount = 0;
            int skipCount = 0;
            int failCount = 0;
            StringBuilder errorMessages = new StringBuilder();
            
            // 1. 添加新角色（在新列表中但不在当前列表中的角色）
            for (String roleCode : newRoleCodes) {
                if (!currentRoleCodes.contains(roleCode)) {
                    try {
                        UserRole userRole = new UserRole();
                        userRole.setUserId(userId);
                        userRole.setRoleCode(roleCode);
                        userRole.setCreatedTime(new Date());
                        
                        int result = userRoleMapper.insert(userRole);
                        if (result > 0) {
                            addCount++;
                        } else {
                            failCount++;
                            errorMessages.append(String.format("添加角色:%s失败; ", roleCode));
                        }
                    } catch (Exception e) {
                        failCount++;
                        errorMessages.append(String.format("添加角色:%s异常:%s; ", roleCode, e.getMessage()));
                        log.warn("添加用户角色失败，用户ID：{}，角色编码：{}", userId, roleCode, e);
                    }
                } else {
                    skipCount++;
                }
            }
            
            // 2. 删除不再需要的角色（在当前列表中但不在新列表中的角色）
            for (String currentRoleCode : currentRoleCodes) {
                if (!newRoleCodes.contains(currentRoleCode)) {
                    try {
                        int result = userRoleMapper.deleteByUserIdIdAndRoleId(userId, currentRoleCode);
                        if (result > 0) {
                            removeCount++;
                        } else {
                            failCount++;
                            errorMessages.append(String.format("删除角色:%s失败; ", currentRoleCode));
                        }
                    } catch (Exception e) {
                        failCount++;
                        errorMessages.append(String.format("删除角色:%s异常:%s; ", currentRoleCode, e.getMessage()));
                        log.warn("删除用户角色失败，用户ID：{}，角色编码：{}", userId, currentRoleCode, e);
                    }
                }
            }
            
            // 构建返回消息
            String message = String.format("用户ID:%d 角色同步完成：新增%d个，删除%d个，保持%d个，失败%d个", 
                    userId, addCount, removeCount, skipCount, failCount);
            if (errorMessages.length() > 0) {
                message += "。错误详情：" + errorMessages.toString();
            }
            
            if (failCount > 0) {
                return Result.fail(message);
            } else {
                return Result.success(message);
            }
        } catch (Exception e) {
            log.error("同步用户角色失败，用户ID：{}", userId, e);
            return Result.fail("角色同步失败：" + e.getMessage());
        }
    }

    /**
     * 处理加密消息
     */
    private WechatMessage handleEncryptedMessage(String requestBody, String msgSignature, String timestamp, String nonce) {
        try {
            // 解析JSON获取加密内容
            JSONObject jsonObj = JSON.parseObject(requestBody);
            String encrypt = jsonObj.getString("Encrypt");

            if (!StringUtils.hasText(encrypt)) {
                log.error("加密消息体为空");
                return null;
            }

            // 验证消息体签名
            if (!WechatCryptoUtil.verifyMsgSignature(wechatMpConfig.getToken(), timestamp, nonce, encrypt, msgSignature)) {
                log.error("消息体签名验证失败");
                return null;
            }

            // 解密消息
            String decryptedMsg = WechatCryptoUtil.decrypt(wechatMpConfig.getEncodingAESKey(), encrypt, wechatMpConfig.getAppid());

            if (!StringUtils.hasText(decryptedMsg)) {
                log.error("消息解密失败");
                return null;
            }

            log.info("解密后的消息: {}", decryptedMsg);

            // 解析XML消息为对象
            return parseXmlMessage(decryptedMsg);

        } catch (Exception e) {
            log.error("处理加密消息失败", e);
            return null;
        }
    }

    /**
     * 处理明文消息
     */
    private WechatMessage handlePlainMessage(String requestBody) {
        try {
            log.info("明文消息: {}", requestBody);
            return parseXmlMessage(requestBody);
        } catch (Exception e) {
            log.error("处理明文消息失败", e);
            return null;
        }
    }

    /**
     * 解析XML消息为对象
     */
    private WechatMessage parseXmlMessage(String xmlContent) {
        try {
            // 简单的XML解析（实际项目建议使用专业的XML解析库）
            WechatMessage message = new WechatMessage();

            message.setToUserName(extractXmlValue(xmlContent, "ToUserName"));
            message.setFromUserName(extractXmlValue(xmlContent, "FromUserName"));
            message.setMsgType(extractXmlValue(xmlContent, "MsgType"));
            message.setEvent(extractXmlValue(xmlContent, "Event"));
            message.setEventKey(extractXmlValue(xmlContent, "EventKey"));
            message.setContent(extractXmlValue(xmlContent, "Content"));

            String createTimeStr = extractXmlValue(xmlContent, "CreateTime");
            if (StringUtils.hasText(createTimeStr)) {
                message.setCreateTime(Long.valueOf(createTimeStr));
            }

            String msgIdStr = extractXmlValue(xmlContent, "MsgId");
            if (StringUtils.hasText(msgIdStr)) {
                message.setMsgId(Long.valueOf(msgIdStr));
            }

            return message;
        } catch (Exception e) {
            log.error("解析XML消息失败", e);
            return null;
        }
    }

    /**
     * 从XML中提取指定标签的值
     */
    private String extractXmlValue(String xml, String tagName) {
        try {
            String startTag = "<" + tagName + ">";
            String endTag = "</" + tagName + ">";
            String cdataStart = "<![CDATA[";
            String cdataEnd = "]]>";

            int start = xml.indexOf(startTag);
            if (start == -1) return null;

            start += startTag.length();
            int end = xml.indexOf(endTag, start);
            if (end == -1) return null;

            String value = xml.substring(start, end).trim();

            // 处理CDATA
            if (value.startsWith(cdataStart) && value.endsWith(cdataEnd)) {
                value = value.substring(cdataStart.length(), value.length() - cdataEnd.length());
            }

            return value.isEmpty() ? null : value;
        } catch (Exception e) {
            log.error("提取XML值失败: {}", tagName, e);
            return null;
        }
    }

    /**
     * 处理具体消息内容
     */
    private String processMessage(WechatMessage message) {
        try {
            log.info("处理微信消息: {}", JSON.toJSONString(message));

            String msgType = message.getMsgType();

            if ("event".equals(msgType)) {
                return handleEvent(message);
            } else if ("text".equals(msgType)) {
                return handleTextMessage(message);
            } else {
                log.info("未处理的消息类型: {}", msgType);
                return ""; // 返回空字符串表示不回复
            }
        } catch (Exception e) {
            log.error("处理消息内容失败", e);
            return "";
        }
    }

    /**
     * 处理事件消息
     */
    private String handleEvent(WechatMessage message) {
        String event = message.getEvent();
        String eventKey = message.getEventKey();

        if ("SCAN".equals(event) || "subscribe".equals(event)) {
            // 扫描二维码事件
            handleQrCodeScan(message.getFromUserName(), eventKey);
            return createTextReply(message, "欢迎关注！");
        } else if ("unsubscribe".equals(event)) {
            // 取消关注事件
            log.info("用户取消关注: {}", message.getFromUserName());
            return "";
        } else {
            log.info("未处理的事件类型: {}", event);
            return "";
        }
    }

    /**
     * 处理文本消息
     */
    private String handleTextMessage(WechatMessage message) {
        String content = message.getContent();

        if ("hello".equalsIgnoreCase(content) || "你好".equals(content)) {
            return createTextReply(message, "您好！欢迎使用我们的服务！");
        } else {
            return createTextReply(message, "感谢您的消息，我们已收到！");
        }
    }

    /**
     * 处理二维码扫描
     */
    private void handleQrCodeScan(String openid, String eventKey) {
        try {
            // 从eventKey中提取场景值
            // SCAN事件: eventKey直接就是sceneId (例如: "123456789")
            // subscribe事件: eventKey格式为 "qrscene_123456789"
            String sceneId = eventKey;
            if (eventKey.startsWith("qrscene_")) {
                sceneId = eventKey.substring(8); // 去掉 "qrscene_" 前缀
            }

            log.info("处理二维码扫描: eventKey={}, 提取的sceneId={}, openid={}", eventKey, sceneId, openid);

            // 检查是否为绑定模式
            String qrCodeKey = WECHAT_QR_CODE_PREFIX + "QR_" + sceneId;
            Object qrCodeData = redisUtils.get(qrCodeKey);
            
            Result<?> loginResult;
            boolean isBindMode = false;
            Integer bindUserId = null;
            
            // 判断是否为绑定模式
            if (qrCodeData instanceof Map) {
                @SuppressWarnings("unchecked")
                Map<String, Object> qrCodeInfo = (Map<String, Object>) qrCodeData;
                Boolean bindMode = (Boolean) qrCodeInfo.get("bindMode");
                if (Boolean.TRUE.equals(bindMode)) {
                    isBindMode = true;
                    bindUserId = (Integer) qrCodeInfo.get("userId");
                    log.info("检测到绑定模式: userId={}", bindUserId);
                }
            }
            
            if (isBindMode && bindUserId != null) {
                // 绑定模式：将微信绑定到现有用户
                loginResult = bindWechatToUser(bindUserId.longValue(), openid);
                log.info("微信绑定处理完成: userId={}, openid={}, success={}", bindUserId, openid, loginResult.getCode() == 200);
            } else {
                // 普通登录模式：自动创建或登录用户
                loginResult = autoCreateUserByQrScan(openid);
                log.info("微信登录处理完成: openid={}, success={}", openid, loginResult.getCode() == 200);
            }
            
            // 将登录结果存储到Redis，供前端轮询
            String scanKey = WECHAT_QR_SCAN_PREFIX + sceneId;
            Map<String, Object> scanResult = new HashMap<>();
            scanResult.put("openid", openid);
            scanResult.put("loginResult", loginResult);
            scanResult.put("timestamp", System.currentTimeMillis());
            scanResult.put("sceneId", sceneId);
            scanResult.put("eventKey", eventKey);
            scanResult.put("bindMode", isBindMode);
            if (bindUserId != null) {
                scanResult.put("userId", bindUserId);
            }
            
            redisUtils.set(scanKey, scanResult, 300); // 5分钟过期

            // 直接存储到二维码ID对应的Redis key，供前端查询
            redisUtils.set(qrCodeKey, scanResult, 600L);
            
            log.info("已存储扫码结果到二维码key: qrCodeKey={}, bindMode={}", qrCodeKey, isBindMode);

        } catch (Exception e) {
            log.error("处理二维码扫描失败: eventKey={}, openid={}", eventKey, openid, e);
            
            // 即使处理失败，也要记录扫描结果
            try {
                String sceneId = eventKey;
                if (eventKey.startsWith("qrscene_")) {
                    sceneId = eventKey.substring(8);
                }
                
                String scanKey = WECHAT_QR_SCAN_PREFIX + sceneId;
                Map<String, Object> scanResult = new HashMap<>();
                scanResult.put("openid", openid);
                scanResult.put("error", "处理失败: " + e.getMessage());
                scanResult.put("timestamp", System.currentTimeMillis());
                scanResult.put("sceneId", sceneId);
                scanResult.put("eventKey", eventKey);
                
                redisUtils.set(scanKey, scanResult, 300);
                
                log.info("扫描失败但已记录: sceneId={}, openid={}, error={}", sceneId, openid, e.getMessage());
            } catch (Exception redisE) {
                log.error("存储扫描结果到Redis失败", redisE);
            }
        }
    }

    /**
     * 创建文本回复
     */
    private String createTextReply(WechatMessage message, String content) {
        long timestamp = System.currentTimeMillis() / 1000;

        return String.format(
            "<xml>" +
            "<ToUserName><![CDATA[%s]]></ToUserName>" +
            "<FromUserName><![CDATA[%s]]></FromUserName>" +
            "<CreateTime>%d</CreateTime>" +
            "<MsgType><![CDATA[text]]></MsgType>" +
            "<Content><![CDATA[%s]]></Content>" +
            "</xml>",
            message.getFromUserName(),
            message.getToUserName(),
            timestamp,
            content
        );
    }

    /**
     * 创建加密响应
     */
    private WechatResponse createEncryptedResponse(String replyContent, String timestamp, String nonce) {
        try {
            // 加密回复内容
            String encrypt = WechatCryptoUtil.encrypt(wechatMpConfig.getEncodingAESKey(), replyContent, wechatMpConfig.getAppid());

            if (encrypt == null) {
                log.error("加密回复消息失败");
                return null;
            }

            // 生成消息体签名
            long currentTimestamp = System.currentTimeMillis() / 1000;
            String msgSignature = WechatCryptoUtil.generateMsgSignature(
                wechatMpConfig.getToken(),
                String.valueOf(currentTimestamp),
                nonce,
                encrypt
            );

            return WechatResponse.encrypted(encrypt, msgSignature, currentTimestamp, nonce);
        } catch (Exception e) {
            log.error("创建加密响应失败", e);
            return null;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> bindDistributorId(BindDistributorIdDTO bindDistributorIdDTO) {
        try {            
            // 参数校验
            if (bindDistributorIdDTO == null) {
                return Result.error("请求参数不能为空");
            }
            
            if (bindDistributorIdDTO.getUserId() == null) {
                return Result.error("用户ID不能为空");
            }
            
            if (bindDistributorIdDTO.getCode() == null || bindDistributorIdDTO.getCode().trim().isEmpty()) {
                return Result.error("分销码不能为空");
            }
            
            if (bindDistributorIdDTO.getType() == null) {
                return Result.error("绑定类型不能为空");
            }
            
            // 查询用户是否存在
            User user = userMapper.selectById(bindDistributorIdDTO.getUserId());
            if (user == null) {
                return Result.error("用户不存在");
            }
            
            // 根据type类型处理不同的绑定逻辑
            if (bindDistributorIdDTO.getType() == 0) {
                // type = 0: 绑定用户关系（设置parent_id）
                return handleUserBinding(bindDistributorIdDTO, user);
            } else if (bindDistributorIdDTO.getType() == 1) {
                // type = 1: 绑定课程分销关系
                return handleCourseDistributorBinding(bindDistributorIdDTO, user);
            } else {
                return Result.error("不支持的绑定类型");
            }
            
        } catch (Exception e) {
            log.error("分销码绑定失败", e);
            return Result.error("绑定失败: " + e.getMessage());
        }
    }
    
    /**
     * 处理用户绑定（设置parent_id）
     */
    private Result<?> handleUserBinding(BindDistributorIdDTO dto, User user) {
        try {

            System.out.println("分销码:::" + dto.getCode());
            User distributor = userMapper.selectByInvitationCode(dto.getCode());
            if (distributor == null) {
                return Result.error("分销码无效");
            }
            
            // 检查是否已经绑定了父级用户
            if (user.getParentId() != null) {
                return Result.error("用户已绑定分销员，无法重复绑定");
            }
            
            // 检查不能绑定自己
            if (distributor.getId().equals(user.getId())) {
                return Result.error("不能绑定自己为分销员");
            }
            
            // 更新用户的parent_id
            int result = userMapper.updateParentId(user.getId(), distributor.getId());
            if (result > 0) {
                log.info("用户绑定分销员成功: userId={}, distributorId={}", user.getId(), distributor.getId());
                return Result.success("绑定成功");
            } else {
                return Result.error("绑定失败");
            }
            
        } catch (Exception e) {
            log.error("处理用户绑定失败", e);
            return Result.error("绑定失败: " + e.getMessage());
        }
    }
    
    /**
     * 处理课程分销绑定
     */
    private Result<?> handleCourseDistributorBinding(BindDistributorIdDTO dto, User user) {
        try {
            // 通过分销码查询课程分销关系
            CourseDistributerRel courseDistributerRel = courseDistributerRelMapper.selectByCode(dto.getCode());
            if (courseDistributerRel == null) {
                return Result.error("分销码无效");
            }
            
            // 检查分销关系是否有效
            if (courseDistributerRel.getStatus() != 1) {
                return Result.error("分销关系已失效");
            }
            
            // 检查是否已经存在相同的绑定关系
            UserDistributorCourseRel existingRel = userDistributorCourseRelMapper.selectByStudentDistributorAndCourse(
                user.getId(), 
                courseDistributerRel.getDistributerId(), 
                courseDistributerRel.getCourseId()
            );
            
            if (existingRel != null) {
                return Result.error("该课程分销关系已存在");
            }
            
            // 创建新的用户-分销员-课程关系记录
            UserDistributorCourseRel newRel = new UserDistributorCourseRel();
            newRel.setStudentId(user.getId());
            newRel.setDistributorId(courseDistributerRel.getDistributerId());
            newRel.setCourseId(courseDistributerRel.getCourseId());
            
            // 处理分销比例，如果为null则设置默认值
            java.math.BigDecimal distributionRatio = courseDistributerRel.getDistributionRatio();
            if (distributionRatio == null) {
                log.warn("分销比例为空，使用默认值0.00: code={}", dto.getCode());
                distributionRatio = java.math.BigDecimal.ZERO;
            }
            newRel.setDistributionRatio(distributionRatio);
            
            newRel.setStatus((short) 1); // 设置为有效状态
            newRel.setCreatedTime(java.time.LocalDateTime.now());
            newRel.setUpdatedTime(java.time.LocalDateTime.now());
            
            // 插入记录
            int result = userDistributorCourseRelMapper.insert(newRel);
            if (result > 0) {
                log.info("课程分销绑定成功: userId={}, distributorId={}, courseId={}", 
                    user.getId(), courseDistributerRel.getDistributerId(), courseDistributerRel.getCourseId());
                return Result.success("课程分销绑定成功");
            } else {
                return Result.error("课程分销绑定失败");
            }
            
        } catch (Exception e) {
            log.error("处理课程分销绑定失败", e);
            return Result.error("绑定失败: " + e.getMessage());
        }
    }
}
